///*
// * Copyright (C) 2007 The Android Open Source Project
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// *      http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
//package android.support.v7.widget;
//
//import android.graphics.Rect;
//import android.view.View;
//import android.view.ViewConfiguration;
//import android.view.ViewGroup;
//
//import java.util.ArrayList;
//import java.util.Collections;
//import java.util.Comparator;
//
///**
// * The algorithm used for finding the next focusable view in a given direction
// * from a view that currently has focus.
// */
//public class FocusFinder2 {
//
//    private static final ThreadLocal<FocusFinder2> tlFocusFinder = new ThreadLocal<FocusFinder2>() {
//        @Override
//        protected FocusFinder2 initialValue() {
//            return new FocusFinder2();
//        }
//    };
//
//    /**
//     * Get the focus finder for this thread.
//     */
//    public static FocusFinder2 getInstance() {
//        return tlFocusFinder.get();
//    }
//
//    final Rect mFocusedRect = new Rect();
//    final Rect mOtherRect = new Rect();
//    final Rect mBestCandidateRect = new Rect();
//    final SequentialFocusComparator mSequentialFocusComparator = new SequentialFocusComparator();
//
//    private final ArrayList<View> mTempList = new ArrayList<View>();
//
//    // enforce thread local access
//    public FocusFinder2() {
//    }
//
//    /**
//     * Find the next view to take focus in root's descendants, starting from the view
//     * that currently is focused.
//     *
//     * @param root      Contains focused. Cannot be null.
//     * @param focused   Has focus now.
//     * @param direction Direction to look.
//     * @return The next focusable view, or null if none exists.
//     */
//    public final View findNextFocus(ViewGroup root, View focused, int direction) {
//        return findNextFocus(root, focused, null, direction);
//    }
//
//    /**
//     * Find the next view to take focus in root's descendants, searching from
//     * a particular rectangle in root's coordinates.
//     *
//     * @param root        Contains focusedRect. Cannot be null.
//     * @param focusedRect The starting point of the search.
//     * @param direction   Direction to look.
//     * @return The next focusable view, or null if none exists.
//     */
//    public View findNextFocusFromRect(ViewGroup root, Rect focusedRect, int direction) {
//        mFocusedRect.set(focusedRect);
//        return findNextFocus(root, null, mFocusedRect, direction);
//    }
//
//    private boolean isInViewTree(View view) {
//        ViewGroup p = (ViewGroup) view.getParent();
//        while (p != null) {
//            if (p.getParent() instanceof ViewGroup)
//                p = (ViewGroup) p.getParent();
//            else
//                break;
//        }
//        if (p == null)
//            return false;
//        return p.getParent() == null ? false : true;
//    }
//
//    private View findNextFocus(ViewGroup root, View focused, Rect focusedRect, int direction) {
//        View next = null;
//        //        if (focused instanceof IFocusController)
//        //            next = ((IFocusController) focused).getFocusView(direction);
//        //        if (next != null){
//        //            if (!(isInViewTree(next) && next.getVisibility() == View.VISIBLE)
//        //                    && next instanceof IFocusController) {
//        //                ((IFocusController) next).clearFocusCache();
//        //            }
//        //        }
//        if (next == null) {
//            if (focused != null) {
//                next = findNextUserSpecifiedFocus(root, focused, direction);
//            }
//            if (next != null) {
//                return next;
//            }
//            ArrayList<View> focusables = mTempList;
//            try {
//                focusables.clear();
//                root.addFocusables(focusables, direction);
//                if (!focusables.isEmpty()) {
//                    next = findNextFocus(root, focused, focusedRect, direction, focusables);
//                }
//            } finally {
//                focusables.clear();
//            }
//        }
//        //        if (next instanceof IFocusController && focused instanceof IFocusController){
//        //            ((IFocusController) focused).setFocusView(next,direction);
//        //            switch (direction){
//        //                case View.FOCUS_LEFT:
//        //                    ((IFocusController) next).setFocusView(focused,View.FOCUS_RIGHT);
//        //                    break;
//        //                case View.FOCUS_RIGHT:
//        //                    ((IFocusController) next).setFocusView(focused,View.FOCUS_LEFT);
//        //                    break;
//        //                case View.FOCUS_UP:
//        //                    ((IFocusController) next).setFocusView(focused,View.FOCUS_DOWN);
//        //                    break;
//        //                case View.FOCUS_DOWN:
//        //                    ((IFocusController) next).setFocusView(focused,View.FOCUS_UP);
//        //                    break;
//        //            }
//        //        }
//        return next;
//    }
//
//    private View findNextUserSpecifiedFocus(ViewGroup root, View focused, int direction) {
//        // check for user specified next focus
//
//        return null;
//    }
//
//    private View findNextFocus(ViewGroup root, View focused, Rect focusedRect, int direction, ArrayList<View> focusables) {
//        if (focused != null) {
//            if (focusedRect == null) {
//                focusedRect = mFocusedRect;
//            }
//            // fill in interesting rect from focused
//            focused.getFocusedRect(focusedRect);
//            root.offsetDescendantRectToMyCoords(focused, focusedRect);
//        } else {
//            if (focusedRect == null) {
//                focusedRect = mFocusedRect;
//                // make up a rect at top left or bottom right of root
//                switch (direction) {
//                    case View.FOCUS_RIGHT:
//                    case View.FOCUS_DOWN:
//                        setFocusTopLeft(root, focusedRect);
//                        break;
//                    case View.FOCUS_FORWARD:
//                        setFocusTopLeft(root, focusedRect);
//                        break;
//
//                    case View.FOCUS_LEFT:
//                    case View.FOCUS_UP:
//                        setFocusBottomRight(root, focusedRect);
//                        break;
//                    case View.FOCUS_BACKWARD:
//                        setFocusBottomRight(root, focusedRect);
//                        break;
//                }
//            }
//        }
//
//        switch (direction) {
//            case View.FOCUS_FORWARD:
//            case View.FOCUS_BACKWARD:
//                return findNextFocusInRelativeDirection(focusables, root, focused, focusedRect, direction);
//            case View.FOCUS_UP:
//            case View.FOCUS_DOWN:
//            case View.FOCUS_LEFT:
//            case View.FOCUS_RIGHT:
//                return findNextFocusInAbsoluteDirection(focusables, root, focused, focusedRect, direction);
//            default:
//                throw new IllegalArgumentException("Unknown direction: " + direction);
//        }
//    }
//
//    private View findNextFocusInRelativeDirection(ArrayList<View> focusables, ViewGroup root, View focused, Rect focusedRect, int direction) {
//        try {
//            // Note: This sort is stable.
//            mSequentialFocusComparator.setRoot(root);
//            mSequentialFocusComparator.setIsLayoutRtl(false);
//            Collections.sort(focusables, mSequentialFocusComparator);
//        } finally {
//            mSequentialFocusComparator.recycle();
//        }
//
//        final int count = focusables.size();
//        switch (direction) {
//            case View.FOCUS_FORWARD:
//                return getNextFocusable(focused, focusables, count);
//            case View.FOCUS_BACKWARD:
//                return getPreviousFocusable(focused, focusables, count);
//        }
//        return focusables.get(count - 1);
//    }
//
//    private void setFocusBottomRight(ViewGroup root, Rect focusedRect) {
//        final int rootBottom = root.getScrollY() + root.getHeight();
//        final int rootRight = root.getScrollX() + root.getWidth();
//        focusedRect.set(rootRight, rootBottom, rootRight, rootBottom);
//    }
//
//    private void setFocusTopLeft(ViewGroup root, Rect focusedRect) {
//        final int rootTop = root.getScrollY();
//        final int rootLeft = root.getScrollX();
//        focusedRect.set(rootLeft, rootTop, rootLeft, rootTop);
//    }
//
//    View findNextFocusInAbsoluteDirection(ArrayList<View> focusables, ViewGroup root, View focused, Rect focusedRect, int direction) {
//        // initialize the best candidate to something impossible
//        // (so the first plausible view will become the best choice)
//        mBestCandidateRect.set(focusedRect);
//        switch (direction) {
//            case View.FOCUS_LEFT:
//                mBestCandidateRect.offset(focusedRect.width() + 1, 0);
//                break;
//            case View.FOCUS_RIGHT:
//                mBestCandidateRect.offset(-(focusedRect.width() + 1), 0);
//                break;
//            case View.FOCUS_UP:
//                mBestCandidateRect.offset(0, focusedRect.height() + 1);
//                break;
//            case View.FOCUS_DOWN:
//                mBestCandidateRect.offset(0, -(focusedRect.height() + 1));
//        }
//
//        View closest = null;
//
//        int numFocusables = focusables.size();
//        for (int i = 0; i < numFocusables; i++) {
//            View focusable = focusables.get(i);
//
//            // only interested in other non-root views
//            if (focusable == focused || focusable == root)
//                continue;
//
//            // get focus bounds of other view in same coordinate system
//            focusable.getFocusedRect(mOtherRect);
//            root.offsetDescendantRectToMyCoords(focusable, mOtherRect);
//
//            if (isBetterCandidate(direction, focusedRect, mOtherRect, mBestCandidateRect)) {
//                mBestCandidateRect.set(mOtherRect);
//                closest = focusable;
//            }
//        }
//        return closest;
//    }
//
//    private static View getNextFocusable(View focused, ArrayList<View> focusables, int count) {
//        if (focused != null) {
//            int position = focusables.lastIndexOf(focused);
//            if (position >= 0 && position + 1 < count) {
//                return focusables.get(position + 1);
//            }
//        }
//        if (!focusables.isEmpty()) {
//            return focusables.get(0);
//        }
//        return null;
//    }
//
//    private static View getPreviousFocusable(View focused, ArrayList<View> focusables, int count) {
//        if (focused != null) {
//            int position = focusables.indexOf(focused);
//            if (position > 0) {
//                return focusables.get(position - 1);
//            }
//        }
//        if (!focusables.isEmpty()) {
//            return focusables.get(count - 1);
//        }
//        return null;
//    }
//
//    /**
//     * Is rect1 a better candidate than rect2 for a focus search in a particular
//     * direction from a source rect?  This is the core routine that determines
//     * the order of focus searching.
//     *
//     * @param direction the direction (up, down, left, right)
//     * @param source    The source we are searching from
//     * @param rect1     The candidate rectangle
//     * @param rect2     The current best candidate.
//     * @return Whether the candidate is the new best.
//     */
//    boolean isBetterCandidate(int direction, Rect source, Rect rect1, Rect rect2) {
//
//        // to be a better candidate, need to at least be a candidate in the first
//        // place :)
//        if (!isCandidate(source, rect1, direction)) {
//            return false;
//        }
//
//        // we know that rect1 is a candidate.. if rect2 is not a candidate,
//        // rect1 is better
//        if (!isCandidate(source, rect2, direction)) {
//            return true;
//        }
//
//        // if rect1 is better by beam, it wins
//        if (beamBeats(direction, source, rect1, rect2)) {
//            return true;
//        }
//
//        // if rect2 is better, then rect1 cant' be :)
//        if (beamBeats(direction, source, rect2, rect1)) {
//            return false;
//        }
//
//        // otherwise, do fudge-tastic comparison of the major and minor axis
//        return (getWeightedDistanceFor(majorAxisDistance(direction, source, rect1), minorAxisDistance(direction, source, rect1)) < getWeightedDistanceFor(majorAxisDistance(direction, source, rect2), minorAxisDistance(direction, source, rect2)));
//    }
//
//    /**
//     * One rectangle may be another candidate than another by virtue of being
//     * exclusively in the beam of the source rect.
//     *
//     * @return Whether rect1 is a better candidate than rect2 by virtue of it being in src's
//     * beam
//     */
//    boolean beamBeats(int direction, Rect source, Rect rect1, Rect rect2) {
//        final boolean rect1InSrcBeam = beamsOverlap(direction, source, rect1);
//        final boolean rect2InSrcBeam = beamsOverlap(direction, source, rect2);
//
//        // if rect1 isn't exclusively in the src beam, it doesn't win
//        if (rect2InSrcBeam || !rect1InSrcBeam) {
//            return false;
//        }
//
//        // we know rect1 is in the beam, and rect2 is not
//
//        // if rect1 is to the direction of, and rect2 is not, rect1 wins.
//        // for example, for direction left, if rect1 is to the left of the source
//        // and rect2 is below, then we always prefer the in beam rect1, since rect2
//        // could be reached by going down.
//        if (!isToDirectionOf(direction, source, rect2)) {
//            return true;
//        }
//
//        // for horizontal directions, being exclusively in beam always wins
//        if ((direction == View.FOCUS_LEFT || direction == View.FOCUS_RIGHT)) {
//            return true;
//        }
//
//        // for vertical directions, beams only beat up to a point:
//        // now, as long as rect2 isn't completely closer, rect1 wins
//        // e.g for direction down, completely closer means for rect2's top
//        // edge to be closer to the source's top edge than rect1's bottom edge.
//        return (majorAxisDistance(direction, source, rect1) < majorAxisDistanceToFarEdge(direction, source, rect2));
//    }
//
//    /**
//     * Fudge-factor opportunity: how to calculate distance given major and minor
//     * axis distances.  Warning: this fudge factor is finely tuned, be sure to
//     * run all focus tests if you dare tweak it.
//     */
//    int getWeightedDistanceFor(int majorAxisDistance, int minorAxisDistance) {
//        return 13 * majorAxisDistance * majorAxisDistance + minorAxisDistance * minorAxisDistance;
//    }
//
//    /**
//     * Is destRect a candidate for the next focus given the direction?  This
//     * checks whether the dest is at least partially to the direction of (e.g left of)
//     * from source.
//     * <p>
//     * Includes an edge case for an empty rect (which is used in some cases when
//     * searching from a point on the screen).
//     */
//    boolean isCandidate(Rect srcRect, Rect destRect, int direction) {
//        switch (direction) {
//            case View.FOCUS_LEFT:
//                return (srcRect.right > destRect.right || srcRect.left >= destRect.right) && srcRect.left > destRect.left;
//            case View.FOCUS_RIGHT:
//                return (srcRect.left < destRect.left || srcRect.right <= destRect.left) && srcRect.right < destRect.right;
//            case View.FOCUS_UP:
//                return (srcRect.bottom > destRect.bottom || srcRect.top >= destRect.bottom) && srcRect.top > destRect.top;
//            case View.FOCUS_DOWN:
//                return (srcRect.top < destRect.top || srcRect.bottom <= destRect.top) && srcRect.bottom < destRect.bottom;
//        }
//        throw new IllegalArgumentException("direction must be one of " + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}.");
//    }
//
//
//    /**
//     * Do the "beams" w.r.t the given direction's axis of rect1 and rect2 overlap?
//     *
//     * @param direction the direction (up, down, left, right)
//     * @param rect1     The first rectangle
//     * @param rect2     The second rectangle
//     * @return whether the beams overlap
//     */
//    boolean beamsOverlap(int direction, Rect rect1, Rect rect2) {
//        switch (direction) {
//            case View.FOCUS_LEFT:
//            case View.FOCUS_RIGHT:
//                return (rect2.bottom >= rect1.top) && (rect2.top <= rect1.bottom);
//            case View.FOCUS_UP:
//            case View.FOCUS_DOWN:
//                return (rect2.right >= rect1.left) && (rect2.left <= rect1.right);
//        }
//        throw new IllegalArgumentException("direction must be one of " + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}.");
//    }
//
//    /**
//     * e.g for left, is 'to left of'
//     */
//    boolean isToDirectionOf(int direction, Rect src, Rect dest) {
//        switch (direction) {
//            case View.FOCUS_LEFT:
//                return src.left >= dest.right;
//            case View.FOCUS_RIGHT:
//                return src.right <= dest.left;
//            case View.FOCUS_UP:
//                return src.top >= dest.bottom;
//            case View.FOCUS_DOWN:
//                return src.bottom <= dest.top;
//        }
//        throw new IllegalArgumentException("direction must be one of " + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}.");
//    }
//
//    /**
//     * @return The distance from the edge furthest in the given direction
//     * of source to the edge nearest in the given direction of dest.  If the
//     * dest is not in the direction from source, return 0.
//     */
//    static int majorAxisDistance(int direction, Rect source, Rect dest) {
//        return Math.max(0, majorAxisDistanceRaw(direction, source, dest));
//    }
//
//    static int majorAxisDistanceRaw(int direction, Rect source, Rect dest) {
//        switch (direction) {
//            case View.FOCUS_LEFT:
//                return source.left - dest.right;
//            case View.FOCUS_RIGHT:
//                return dest.left - source.right;
//            case View.FOCUS_UP:
//                return source.top - dest.bottom;
//            case View.FOCUS_DOWN:
//                return dest.top - source.bottom;
//        }
//        throw new IllegalArgumentException("direction must be one of " + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}.");
//    }
//
//    /**
//     * @return The distance along the major axis w.r.t the direction from the
//     * edge of source to the far edge of dest. If the
//     * dest is not in the direction from source, return 1 (to break ties with
//     * {@link #majorAxisDistance}).
//     */
//    static int majorAxisDistanceToFarEdge(int direction, Rect source, Rect dest) {
//        return Math.max(1, majorAxisDistanceToFarEdgeRaw(direction, source, dest));
//    }
//
//    static int majorAxisDistanceToFarEdgeRaw(int direction, Rect source, Rect dest) {
//        switch (direction) {
//            case View.FOCUS_LEFT:
//                return source.left - dest.left;
//            case View.FOCUS_RIGHT:
//                return dest.right - source.right;
//            case View.FOCUS_UP:
//                return source.top - dest.top;
//            case View.FOCUS_DOWN:
//                return dest.bottom - source.bottom;
//        }
//        throw new IllegalArgumentException("direction must be one of " + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}.");
//    }
//
//    /**
//     * Find the distance on the minor axis w.r.t the direction to the nearest
//     * edge of the destination rectangle.
//     *
//     * @param direction the direction (up, down, left, right)
//     * @param source    The source rect.
//     * @param dest      The destination rect.
//     * @return The distance.
//     */
//    static int minorAxisDistance(int direction, Rect source, Rect dest) {
//        switch (direction) {
//            case View.FOCUS_LEFT:
//            case View.FOCUS_RIGHT:
//                // the distance between the center verticals
//                return Math.abs(((source.top + source.height() / 2) - ((dest.top + dest.height() / 2))));
//            case View.FOCUS_UP:
//            case View.FOCUS_DOWN:
//                // the distance between the center horizontals
//                return Math.abs(((source.left) - ((dest.left))));
//        }
//        throw new IllegalArgumentException("direction must be one of " + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}.");
//    }
//
//    /**
//     * Find the nearest touchable view to the specified view.
//     *
//     * @param root      The root of the tree in which to search
//     * @param x         X coordinate from which to start the search
//     * @param y         Y coordinate from which to start the search
//     * @param direction Direction to look
//     * @param deltas    Offset from the <x, y> to the edge of the nearest view. Note that this array
//     *                  may already be populated with values.
//     * @return The nearest touchable view, or null if none exists.
//     */
//    public View findNearestTouchable(ViewGroup root, int x, int y, int direction, int[] deltas) {
//        ArrayList<View> touchables = root.getTouchables();
//        int minDistance = Integer.MAX_VALUE;
//        View closest = null;
//
//        int numTouchables = touchables.size();
//
//        int edgeSlop = ViewConfiguration.get(root.getContext()).getScaledEdgeSlop();
//
//        Rect closestBounds = new Rect();
//        Rect touchableBounds = mOtherRect;
//
//        for (int i = 0; i < numTouchables; i++) {
//            View touchable = touchables.get(i);
//
//            // get visible bounds of other view in same coordinate system
//            touchable.getDrawingRect(touchableBounds);
//
//            root.offsetDescendantRectToMyCoords(touchable, touchableBounds);
//
//            if (!isTouchCandidate(x, y, touchableBounds, direction)) {
//                continue;
//            }
//
//            int distance = Integer.MAX_VALUE;
//
//            switch (direction) {
//                case View.FOCUS_LEFT:
//                    distance = x - touchableBounds.right + 1;
//                    break;
//                case View.FOCUS_RIGHT:
//                    distance = touchableBounds.left;
//                    break;
//                case View.FOCUS_UP:
//                    distance = y - touchableBounds.bottom + 1;
//                    break;
//                case View.FOCUS_DOWN:
//                    distance = touchableBounds.top;
//                    break;
//            }
//
//            if (distance < edgeSlop) {
//                // Give preference to innermost views
//                if (closest == null || closestBounds.contains(touchableBounds) || (!touchableBounds.contains(closestBounds) && distance < minDistance)) {
//                    minDistance = distance;
//                    closest = touchable;
//                    closestBounds.set(touchableBounds);
//                    switch (direction) {
//                        case View.FOCUS_LEFT:
//                            deltas[0] = -distance;
//                            break;
//                        case View.FOCUS_RIGHT:
//                            deltas[0] = distance;
//                            break;
//                        case View.FOCUS_UP:
//                            deltas[1] = -distance;
//                            break;
//                        case View.FOCUS_DOWN:
//                            deltas[1] = distance;
//                            break;
//                    }
//                }
//            }
//        }
//        return closest;
//    }
//
//
//    /**
//     * Is destRect a candidate for the next touch given the direction?
//     */
//    private boolean isTouchCandidate(int x, int y, Rect destRect, int direction) {
//        switch (direction) {
//            case View.FOCUS_LEFT:
//                return destRect.left <= x && destRect.top <= y && y <= destRect.bottom;
//            case View.FOCUS_RIGHT:
//                return destRect.left >= x && destRect.top <= y && y <= destRect.bottom;
//            case View.FOCUS_UP:
//                return destRect.top <= y && destRect.left <= x && x <= destRect.right;
//            case View.FOCUS_DOWN:
//                return destRect.top >= y && destRect.left <= x && x <= destRect.right;
//        }
//        throw new IllegalArgumentException("direction must be one of " + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}.");
//    }
//
//    /**
//     * Sorts views according to their visual layout and geometry for default tab order.
//     * This is used for sequential focus traversal.
//     */
//    private static final class SequentialFocusComparator implements Comparator<View> {
//        private final Rect mFirstRect = new Rect();
//        private final Rect mSecondRect = new Rect();
//        private ViewGroup mRoot;
//        private boolean mIsLayoutRtl;
//
//        public void recycle() {
//            mRoot = null;
//        }
//
//        public void setRoot(ViewGroup root) {
//            mRoot = root;
//        }
//
//        public void setIsLayoutRtl(boolean b) {
//            mIsLayoutRtl = b;
//        }
//
//        public int compare(View first, View second) {
//            if (first == second) {
//                return 0;
//            }
//
//            getRect(first, mFirstRect);
//            getRect(second, mSecondRect);
//
//            if (mFirstRect.top < mSecondRect.top) {
//                return -1;
//            } else if (mFirstRect.top > mSecondRect.top) {
//                return 1;
//            } else if (mFirstRect.left < mSecondRect.left) {
//                return mIsLayoutRtl ? 1 : -1;
//            } else if (mFirstRect.left > mSecondRect.left) {
//                return mIsLayoutRtl ? -1 : 1;
//            } else if (mFirstRect.bottom < mSecondRect.bottom) {
//                return -1;
//            } else if (mFirstRect.bottom > mSecondRect.bottom) {
//                return 1;
//            } else if (mFirstRect.right < mSecondRect.right) {
//                return mIsLayoutRtl ? 1 : -1;
//            } else if (mFirstRect.right > mSecondRect.right) {
//                return mIsLayoutRtl ? -1 : 1;
//            } else {
//                // The view are distinct but completely coincident so we consider
//                // them equal for our purposes.  Since the sort is stable, this
//                // means that the views will retain their layout order relative to one another.
//                return 0;
//            }
//        }
//
//        private void getRect(View view, Rect rect) {
//            view.getDrawingRect(rect);
//            mRoot.offsetDescendantRectToMyCoords(view, rect);
//        }
//    }
//}
